using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Net;
using System.Text;
using System.Xml;
using PHSRAG.SharePointUtility;
using PHSRAG.SharePointUtility.SPLists;
namespace PHSRAG.SharePointUtility
{
    /// <summary>
    /// Used to upload documents and get documents
    /// </summary>
    public class DocumentLibrary
    {

        public ICredentials Credentials;

        public DocumentLibrary()
        {
            string uname = ConfigurationManager.AppSettings["UserName"].ToString();
            string pword = ConfigurationManager.AppSettings["Password"].ToString();
            string domain = ConfigurationManager.AppSettings["Domain"].ToString();
            NetworkCredential nc = new NetworkCredential(uname, pword, domain);
            Credentials = nc;
        }




        /// <summary>
        /// This is used to create folders if they are not already existing
        /// </summary>
        /// <param name="destinationUrl"></param>
        /// <param name="baseUrl"></param>
        public void CreateDocumentFolderStructure(string destinationUrl, string baseUrlWithDocLibName)
        {
            string[] folders = destinationUrl.Split('/');
            string root = baseUrlWithDocLibName;
            for (int i = 0; i < folders.Length; i++)
            {
                root += "/" + folders[i];
                if (i >= 0)
                {
                    CreateFolder(root);
                }
            }

        }

        /// <summary>
        /// Upload the file to sharepoint if there is problem at share point
        /// it throws errors
        /// 405 method not allowed
        /// 409 conflict occured
        /// 400 bad request
        /// </summary>
        /// <param name="sharepointUrl"></param>
        /// <param name="bytes"></param>
        public void SaveFileToSharePoint(string fullUrl, string filePath)
        {
            string baseUrlWithDocLibName = GetBaseUrl(fullUrl);
            if (fullUrl.LastIndexOf("/") > 0)
            {
                CreateDocumentFolderStructure(fullUrl.Substring(baseUrlWithDocLibName.Length + 1, fullUrl.LastIndexOf("/") - (baseUrlWithDocLibName.Length + 1)), baseUrlWithDocLibName);
            }

            WebResponse response = null;

            try
            {
                WebRequest request = WebRequest.Create(fullUrl);
                request.Credentials = Credentials;
                request.Method = "PUT";
                // Allocate a 1 KB buffer to transfer the file contents.
                // You can adjust the buffer size as needed, depending on
                // the number and size of files being uploaded.
                byte[] buffer = new byte[1024];

                // Write the contents of the local file to the request stream.
                using (Stream stream = request.GetRequestStream())
                using (FileStream fsWorkbook = File.Open(filePath,
                      FileMode.Open, FileAccess.Read))
                {
                    int i = fsWorkbook.Read(buffer, 0, buffer.Length);

                    while (i > 0)
                    {
                        stream.Write(buffer, 0, i);
                        i = fsWorkbook.Read(buffer, 0, buffer.Length);
                    }
                }

                // Make the PUT request.
                response = request.GetResponse();
            }
            catch
            {
                throw;
            }
            finally
            {
                if (response != null) response.Close();
            }


        }



        /// <summary>
        /// Create the folder, if already existing catch exception and carry on
        /// </summary>
        /// <param name="folderURL"></param>
        /// <returns></returns>
        private bool CreateFolder(string folderURL)
        {
            try
            {
                WebRequest request = WebRequest.Create(folderURL);
                request.Credentials = Credentials;
                request.Method = "MKCOL";
                WebResponse response = request.GetResponse();
                response.Close();
                return true;
            }
            catch (WebException ex)
            {
                string exception = ex.ToString();
                return false;
            }
        }


        public byte[] GetFileFromSharePoint(string destinationUrl)
        {
            byte[] buffer = new byte[1024];
            byte[] data = null;
            try
            {
                WebRequest request = WebRequest.Create(destinationUrl);
                request.Credentials = Credentials;
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                using (Stream stream = response.GetResponseStream())
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        while (true)
                        {
                            int read = stream.Read(buffer, 0, buffer.Length);
                            if (read <= 0)
                            {
                                data = ms.ToArray();
                                break;
                            }
                            ms.Write(buffer, 0, read);
                        }
                    }
                }

                response.Close();
            }
            catch (WebException ex)
            {

                throw ex;
            }
            return data;
        }


        /// <summary>
        /// Update columns
        /// </summary>
        /// <param name="listUrl">InsightDcouments</param>
        /// <param name="docLib">InsightDcouments</param>
        /// <param name="htMetadata">coulmns and values</param>
        /// <param name="destinationUrl">InsightDcouments/protocolId//filname with extenstion</param>
        public void UpdateMetadata(string fullUrl, Hashtable htMetadata)
        {
            XmlDocument oDoc = new System.Xml.XmlDocument();
            System.Xml.XmlElement elBatch = oDoc.CreateElement("Batch");


            Lists spList = new Lists();
            spList.Credentials = Credentials;
            spList.Url = GetListUrl(fullUrl) + "/_vti_bin/lists.asmx";
            string fileRef = fullUrl;
            string docLib = ConfigurationManager.AppSettings["DocLibName"];
            //Update columns
            System.Xml.XmlNode ndListView = spList.GetListAndView(docLib, "");
            string strListID = ndListView.ChildNodes[0].Attributes["Name"].Value;

            StringBuilder strBatch = new StringBuilder(string.Format("<Method ID='1' Cmd='Update'>" +
                                "  <Field Name='ID'/>" +
                                 "  <Field Name='FileRef'>{0}</Field>", fileRef));

            foreach (string key in htMetadata.Keys)
            {
                strBatch.Append(string.Format("<Field Name='{0}'>{1}</Field>", key.ToString(), htMetadata[key].ToString()));


            }
            strBatch.Append("</Method>");


            elBatch.SetAttribute("OnError", "Continue");
            elBatch.SetAttribute("ListVersion", "1");
            elBatch.InnerXml = strBatch.ToString();
            XmlNode xNode = spList.UpdateListItems(strListID, elBatch);



        }

        private string GetBaseUrl(string fullUrl)
        {
            string baseUrl = string.Empty;
            string[] baseUrlArray = fullUrl.Split('/');

            for (int iCount = 0; iCount < 6; iCount++)
            {
                if (iCount == 0)
                {
                    baseUrl += baseUrlArray[iCount];
                }
                else
                {
                    baseUrl += "/" + baseUrlArray[iCount];
                }
            }
            return baseUrl;
        }

        private string GetListUrl(string fullUrl)
        {
            string baseUrl = string.Empty;
            string[] baseUrlArray = fullUrl.Split('/');

            for (int iCount = 0; iCount < 5; iCount++)
            {
                if (iCount == 0)
                {
                    baseUrl += baseUrlArray[iCount];
                }
                else
                {
                    baseUrl += "/" + baseUrlArray[iCount];
                }
            }
            return baseUrl;
        }

        public void DeleteDocument(string fullUrl)
        {

            XmlDocument oDoc = new System.Xml.XmlDocument();
            System.Xml.XmlElement elBatch = oDoc.CreateElement("Batch");


            Lists spList = new Lists();
            spList.Credentials = Credentials;
            spList.Url = GetListUrl(fullUrl) + "/_vti_bin/lists.asmx";
            string fileRef = fullUrl;
            string docLib = ConfigurationManager.AppSettings["DocLibName"];
            //Update columns
            System.Xml.XmlNode ndListView = spList.GetListAndView(docLib, "");
            string strListID = ndListView.ChildNodes[0].Attributes["Name"].Value;

            StringBuilder strBatch = new StringBuilder(string.Format("<Method ID='1' Cmd='Delete'>" +
                                "  <Field Name='ID'/>" +
                                 "  <Field Name='FileRef'>{0}</Field>", fileRef));


            strBatch.Append("</Method>");
            elBatch.SetAttribute("OnError", "Continue");
            elBatch.SetAttribute("ListVersion", "1");
            elBatch.InnerXml = strBatch.ToString();
            XmlNode xNode = spList.UpdateListItems(strListID, elBatch);


        }
    }

}